import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import libsvm.*;

/**
 * All functions to do with classifying articles
 * @author tomalteman
 *
 */
public class Classifier {
	
	private static int debug=0;
	private static double threshold = 0.65;
	
	//Locations for which local model is trained for
	private static String[] local = {"manchester","bristol","durham","london"};
	
	//Value of non local source reduction
	private static double reduce = 0.1;
	
	
	public static ArrayList<article> classify(ArrayList<article> arts)
	{
		String in = "-r classifier/scaling classifier/predict";
		String pred = "-b 1 classifier/predict.scale classifier/train.model classifier/predict.output";
		
		svm_scale s = new svm_scale();
		
		//Convert article array into predict file
		dataset.getPredict(arts,false,0);
		
		try {
			s.run(in.split(" "));
			svm_predict.run(pred.split(" "));
		} catch (IOException ioe) {
			System.err.println("SVM ERROR: " + ioe);
		}
		
		ArrayList<String> output = TFile.read(new File("classifier/predict.output"));
		ArrayList<String> predi = TFile.read(new File("classifier/predict"));
		String str;
		article art;
		ArrayList<article> out = new ArrayList<article>();
		
		if(debug==1)
		{
			System.out.println("Arts are "+arts.size());
			System.out.println("Output has "+output.size());
			System.out.println("Predict has "+predi.size());
		}
		
		for(int i=1;i<output.size();i++)
		{
			str = output.get(i);
			art = arts.get(i-1);
			
			art.category = getLabel(str);
			
			if(debug==1)
			{
				System.out.println(art.getTitle() + " " + art.category);
			}
			
			out.add(art);
		}
		
		return out;
	}
	
	private static int getLabel(String s)
	{
		String[] split = s.split(" ");
		if(debug ==2) System.out.println(s);
		if(debug ==2) System.out.println("SPLIT LENGTH "+split.length);
		
		int lbl = (int) Double.parseDouble(split[0]);
		
		//If no value is above threshold then cant be categorised correctly
		boolean pass = false;
		
		for(int i=1;i<split.length;i++)
		{
			if(debug==2) System.out.print(split[i]+ " ");
			if(Double.parseDouble(split[i]) >= threshold)
				{
					pass = true;  
					break;
				}
		}
		if(debug==2) System.out.println();
		
		if(pass) return lbl;
		
		return -1 * lbl;
	}
	
	private static void doList()
	{
		System.out.println("---- tp="+" fp="+" fn="+" tn=");
		//for(double d=0.5;d<1.0;d=d+0.05)
		for(int x=50;x<60;x=x+10)
		{
		//{
			threshold = 0;
			String in = "-r classifier/localscaling training/class/localpredict";
			String pred = "-b 1 classifier/predict.scale classifier/list.model training/class/predict.output";
		
		svm_scale s = new svm_scale();
		
		try {
			s.run(in.split(" "));
			svm_predict.run(pred.split(" "));
		} catch (IOException ioe) {
			System.err.println("SVM ERROR: " + ioe);
		}
		
		ArrayList<String> output = TFile.read(new File("training/class/predict.output"));
		//ArrayList<String> predi = TFile.read(new File("classifier/predict"));
		String str;
		article art;
		ArrayList<article> out = new ArrayList<article>();

		int topic =0, tp=0, fp=0, fn =0, tn=0;
		
		for(int i=0;i<34;i++)
		{
			if(i<17) topic=1;
			else if(i<100) topic =2;
			else if(i<150) topic = 2;
			else topic = 2;
			
			int label = getLabel(output.get(i+1));
			//System.out.println(label);
			//System.out.println(i);
			
			if(label != 1) label = 2;
				
			if(topic == label)
			{
				if(topic != 1) tn++;
				else tp++;
			}
			else
			{
				if(label != 1) fn++;
				else fp++;
			}
		}
		System.out.print(x);
		System.out.println("\t"+tp+"\t"+fp+"\t"+fn+"\t"+tn);
		}
	}
	
	private static void doMulti()
	{
		int test = 14;
		
		String[] st = {"news","business","entertainment","sports"};
		
		for(int z=6;z<test;z++)
		{
			//dataset.testFromTrain(st,75,50,z);
		String in = "-r classifier/scaling classifier/predict";
		String pred = "-b 1 classifier/predict.scale classifier/train.model training/class/predict.output";
		
		svm_scale s = new svm_scale();
		
		try {
			s.run(in.split(" "));
			svm_predict.run(pred.split(" "));
		} catch (IOException ioe) {
			System.err.println("SVM ERROR: " + ioe);
		}
		
		ArrayList<String> output = TFile.read(new File("training/class/predict.output"));
		ArrayList<String> predi = TFile.read(new File("classifier/predict"));
		String str;
		article art;
		ArrayList<article> out = new ArrayList<article>();

		int topic =0, tp=0, fp=0, fn =0, tn=0,counter=0;
		
		for(int i=0;i<200;i++)
		{
			if(i<50) topic=1;
			else if(i<100) topic =2;
			else if(i<150) topic = 3;
			else topic = 4;
			
			int label = getLabel(output.get(i+1));
			
			
			if(label < 0) label = 1;
				
			if(topic == label)
			{
				if(topic == 1) tn++;
				else tp++;
			}
			else
			{
				if(label == 1) fn++;
				else fp++;
			}
		}
		}
	}
	
	
	private static void doRoc()
	{
		System.out.println("---- tp="+" fp="+" fn="+" tn=");
		//for(double d=0.5;d<1.0;d=d+0.05)
		for(int x=50;x<150;x=x+10)
		{
		//{
			threshold = 0;
		String in = "-r training/class/multi/s"+x+" training/class/multi/predict"+x;
		String pred = "-b 1 classifier/predict.scale training/class/multi/t"+x+".model training/class/predict.output";
		
		svm_scale s = new svm_scale();
		
		try {
			s.run(in.split(" "));
			svm_predict.run(pred.split(" "));
		} catch (IOException ioe) {
			System.err.println("SVM ERROR: " + ioe);
		}
		
		ArrayList<String> output = TFile.read(new File("training/class/predict.output"));
		//ArrayList<String> predi = TFile.read(new File("classifier/predict"));
		String str;
		article art;
		ArrayList<article> out = new ArrayList<article>();

		int topic =0, tp=0, fp=0, fn =0, tn=0;
		
		for(int i=0;i<199;i++)
		{
			if(i<50) topic=1;
			else if(i<100) topic =2;
			else if(i<150) topic = 3;
			else topic = 4;
			
			int label = getLabel(output.get(i+1));
			
			
			if(label < 0) label = 1;
				
			if(topic == label)
			{
				if(topic == 1) tn++;
				else tp++;
			}
			else
			{
				if(label == 1) fn++;
				else fp++;
			}
		}
		System.out.print(x);
		System.out.println("\t"+tp+"\t"+fp+"\t"+fn+"\t"+tn);
		}
	}
	
	///////////////////////////////
	///// Location classifier
	//////////////////////////////
	
	public static ArrayList<article> localClassify(ArrayList<article> arts, String loc)
	{
		int label;
		
		//No point continuing if location is not trained
		if((label = findLoc(loc)) == -1) return doLocRank(arts,loc);
		
		String in = "-r classifier/localscaling classifier/predict";
		String pred = "-b 1 classifier/predict.scale classifier/localtrain.model classifier/predict.output";
		
		svm_scale s = new svm_scale();
		
		//Convert article array into predict file
		dataset.getPredict(arts,true,0);
		
		try {
			s.run(in.split(" "));
			svm_predict.run(pred.split(" "));
		} catch (IOException ioe) {
			System.err.println("SVM ERROR: " + ioe);
		}
		
		ArrayList<String> output = TFile.read(new File("classifier/predict.output"));
		ArrayList<String> predi = TFile.read(new File("classifier/predict"));
		String str;
		article art;
		ArrayList<article> out = new ArrayList<article>();
		
		if(debug==1)
		{
			System.out.println("Arts are "+arts.size());
			System.out.println("Output has "+output.size());
			System.out.println("Predict has "+predi.size());
		}
		
		String[] split, source;
		
		for(int i=1;i<output.size();i++)
		{
			str = output.get(i);
			art = arts.get(i-1);
			
			//locRank is decision value for desired label
			split = str.split(" ");
			art.localRank = Double.parseDouble(split[label+1]);
			
			//iF source is not uk then reduce likelihood of it being local
			if(!art.getSource().toLowerCase().contains("uk") && !art.getSource().toLowerCase().contains("kingdom")) 
				{
					if(debug==4) System.out.println(art.getTitle()+" has source non-uk " + art.getSource());
					art.localRank = art.localRank - reduce;
				}
			
			if(debug==1) System.out.println("Label is "+split[0]);
			art.location = Double.parseDouble(split[0]);
			
			//Get first two digits and multpily by 100
			art.localRank = (double) ((int) (art.localRank*100));
			
			//Add naive calc
			art = locRank(loc,art);
			
			out.add(art);
		}
		
		return out;
	}
	
	/**
	 * Gets index of location thus class label for classifier
	 * Returns -1 if location is not trained
	 * @param loc
	 * @return
	 */
	private static int findLoc(String loc)
	{
		for(int i=0;i<local.length;i++) if(local[i].equals(loc)) return i;
		
		return -1;
	}
	
	/**
	 * Extract all nouns from a text
	 * Boolean loc indicates whether using for locations or feature addition
	 */
	public static wordcount nounExt(String text, boolean loc)
	{
		wordcount list = new wordcount();
		String word="",comb="";
		char[] data = text.toCharArray();
		//System.out.println(data.length);
		String add="-";
		
		if(loc) add = " ";
		
		//Go through array and add to string until space of invlaid char reached
		for(int i=0;i<data.length;i++)
		{
			//System.out.println(i);
			//Append to word string if letter or digit
			if(Character.isLetterOrDigit(data[i])) word = word + Character.toString(data[i]);
			//If ending sentence then or punctuation then end comb
			else if((data[i] == '.') || (data[i] == '?') || (data[i] == '!') || (data[i] == ';') || (data[i] == ','))
				{
				
					if((word.length()>0) && Character.isUpperCase(word.charAt(0)))
					{
						
						if(!Stopwords.isStopword(word))
						{
							comb = comb + add +word;
							if(loc)
							{
								if(debug==1) System.out.println("Adding1 "+comb);
								if(comb.trim().length()>0) list.add(comb.trim().toLowerCase());
							}
							else if((comb.lastIndexOf("-")>1)) 
							{
								if(debug==1) System.out.println("Adding2 "+comb);
								if(comb.trim().length()>0) list.add(comb.trim().toLowerCase().substring(1));
							}
						}
						word = "";
					}
				
					comb="";
					word="";
				}
			//If hyphen then do nothing
			else if(data[i] == '-') ;
			//If word is not empty, and 1st letter is capitalised
			else if((word.length()>0) && Character.isUpperCase(word.charAt(0)))
			{
				
				if(!Stopwords.isStopword(word))
				{
					if(loc) 
						{
							if(debug==1) System.out.println("Adding3 "+word);
							list.add(word.toLowerCase().trim());
							if(debug==1) System.out.println("Adding4 "+comb);
							if(!comb.equals(word)) list.add(comb.toLowerCase().trim());
						}
					comb = comb + add +word;
				}
				word = "";
			}
			else if(word.length()>0) 
				{
					if(loc)
					{
						if(debug==1) System.out.println("Adding5 "+comb);
						if(comb.trim().length()>0) list.add(comb.trim().toLowerCase());
					}
					else if((comb.lastIndexOf("-")>1)) 
					{
						if(debug==1) System.out.println("Adding6 "+comb);
						if(comb.trim().length()>0) list.add(comb.trim().toLowerCase().substring(1));
					}
					
					comb = "";
					word = "";
					
				}
		}
		
		
		if(debug>=1) 
			{
				ArrayList<String> lista = list.getList(false);
				System.out.println("NOUN LIST:");
				for(int i=0;i<lista.size();i++) 
					{
						System.out.println(lista.get(i));
					}
			}
		
		return list;
	}
	
	public static wordcount nounExtract(String text, boolean loc)
	{
		wordcount list = new wordcount();
		String word="",comb="";
		char[] data = text.toCharArray();
		//System.out.println(data.length);
		String add="-";
		
		if(loc) add = " ";
		
		//Go through array and add to string until space of invlaid char reached
		for(int i=0;i<data.length;i++)
		{
			//System.out.println(i);
			//Append to word string if letter or digit
			if(Character.isLetterOrDigit(data[i])) word = word + Character.toString(data[i]);
			//If ending sentence then or punctuation then end comb
			else if((data[i] == '.') || (data[i] == '?') || (data[i] == '!') || (data[i] == ';') || (data[i] == ','))
				{
				
					if((word.length()>0) && Character.isUpperCase(word.charAt(0)))
					{
						
						if(!Stopwords.isStopword(word))
						{
							comb = comb + add +word;
							if(loc)
							{
								if(debug==1) System.out.println("Adding1 "+comb);
								if(comb.trim().length()>0) list.add(comb.trim().toLowerCase());
							}
							else if((comb.lastIndexOf("-")>1)) 
							{
								if(debug==1) System.out.println("Adding2 "+comb);
								if(comb.trim().length()>0) list.add(comb.trim().toLowerCase().substring(1));
							}
						}
						word = "";
					}
				
					comb="";
					word="";
				}
			//If hyphen then do nothing
			else if(data[i] == '-') ;
			//If word is not empty, and 1st letter is capitalised
			else if((word.length()>0) && Character.isUpperCase(word.charAt(0)))
			{
				
				if(!Stopwords.isStopword(word))
				{
					if(loc) 
						{
							if(debug==1) System.out.println("Adding3 "+word);
							list.add(word.toLowerCase().trim());
							if(debug==1) System.out.println("Adding4 "+comb);
							if(!comb.equals(word)) list.add(comb.toLowerCase().trim());
						}
					comb = comb + add +word;
				}
				word = "";
			}
			else if(word.length()>0) 
				{
					if(loc)
					{
						if((comb.trim().length()>0) && (comb.charAt(0)!=' '))
						{
							if(debug==1) System.out.println("Adding5 :"+comb);
							list.add(comb.trim().toLowerCase());
						}
					}
					else if((comb.lastIndexOf("-")>1)) 
					{
						if((comb.trim().length()>0) && (comb.charAt(0)!=' '))
						{
							if(debug==1) System.out.println("Adding6 "+comb);
							if(comb.trim().length()>0) list.add(comb.trim().toLowerCase().substring(1));
						}
					}
					
					comb = "";
					word = "";
					
				}
		}
		
		
		if(debug>=1) 
			{
				ArrayList<String> lista = list.getList(false);
				System.out.println("NOUN LIST:");
				for(int i=0;i<lista.size();i++) 
					{
						System.out.println(lista.get(i));
					}
			}
		
		return list;
	}
	
	/**
	 * Get wordcount of locations from text
	 * @param text
	 * @return
	 */
	public static wordcount getLocs(String text, String place)
	{
		wordcount wc = new wordcount();
		locList loc = new locList(1);
		String l= "";
		HashMap<String,Integer> hash = loc.getHash(place);
		int count = 0;
		
		//Get all nouns
		wordcount nouns = nounExtract(text,true);
		
		//Extract locations from noun list
		for(int i=0;i<nouns.keys.size();i++)
		{
			l = nouns.keys.get(i).toLowerCase();
			
			if(hash.containsKey(l))
			{
				if(hash.get(l)==1) count = count + nouns.getCount(l)*2;
				else if(hash.get(l)==2) count = count + nouns.getCount(l);
				else count = count - nouns.getCount(l)*2;
			}
			else if(loc.contains(l))
				{
					wc.add(l, nouns.getCount(l)*2);
					if(debug==2)
						{
							System.out.println("add location "+l);
							System.out.println("Total is :"+ wc.getTotal());
						}
				}
		}
		
		//Once count is done add to wordcount
		wc.add(place,count);
		
		if(debug>=1) 
		{
			ArrayList<String> lista = wc.getList(false);
			System.out.println("LOC LIST:");
			for(int i=0;i<lista.size();i++) System.out.println(lista.get(i));
			System.out.println("TOTAL: "+wc.getTotal());
		}
		
		return wc;
	}
	
	/**
	 * Gets locRank for each article in list
	 * @param loc
	 * @param arts
	 * @return
	 */
	public static ArrayList<article> doLocRank(ArrayList<article> arts, String loc)
	{
		article art;
		ArrayList<article> n = new ArrayList<article>();
		
		for(int i=0;i<arts.size();i++)
		{
			n.add(locRank(loc,arts.get(i)));
		}
		
		return n;
	}
	
	/**
	 * Adds extra naive location ranking 
	 * @param loc
	 * @param art
	 * @return
	 */
	public static article locRank(String loc, article art)
	{
		String text = art.getText() + " " + art.getTitle();
		wordcount wc = getLocs(text, loc);
		loc = loc.toLowerCase();
		
		//If string is not contained within wc then location not mentioned in text
		if(!wc.contains(loc))
		{
			if(debug==1) System.out.println("Rank: 0 for "+loc +"as not present");
			return art;
		}
		
		//Get count of location
		int locCount = wc.getCount(loc);
		
		//Get proportion of locations counts that refer to desired
		double locProp = ((double) locCount) / ((double) (wc.getTotal()));
		
		//Divide by two
		//locProp = locProp/2;
		
		if(debug>=2) System.out.println("Calc prop rank "+locCount + " / "+ (wc.getTotal()));
		if(debug>=1) System.out.println("Proportion Rank: "+locProp+" for "+loc);
		
		if(wc.keys.size()<1) return art;
		else if(wc.keys.size()<2) 
			{
				art.localRank = art.localRank +0.99;
				//System.out.println(art.localRank);
				return art;
			}
		
		//Compare locCount to average count for a location
		double av = ((double) (wc.getTotal()-locCount)) / ((double) wc.keys.size()-1);
		double locAv = ((double) locCount) / av;
		
		//Divide by 2
		//locAv = locAv/2;
		
		//if(debug==1) System.out.println("LocalRank add "+(locAv+locProp)/100);
		
		//Store locaRank
		art.localRank = art.localRank + locProp;
		
		//if(debug>=2) System.out.println("Av is " + (wc.getTotal()-locCount) + " / "+ (wc.keys.size()-1));
		//if(debug>=2) System.out.println("Cacl locAv is "+locCount+" / "+ av);
		//if(debug>=1) System.out.println("Average Count Ratio Rank: "+locAv+" for "+loc);
		
		if(debug>=1) System.out.println("Local Rank is "+ art.localRank);
		
		return art;
	}
	
	
/////////////////////////////////////////////
	
	public static void main(String[] args)
	{
		/*ArrayList<article> art = new ArrayList<article>();
		art.add(new article());
		art.add(new article());
		classify(art);*/
		
		//Test noun extract
		article art = new article();
		art.setText("Two new features TRUEMA should make Canterbury  Entries make Keynsham. this year's Kona Bristol Bikefest more enjoyable than ever a three-hour novice race and an additional camping area complete with showers. The event takes place at Ashton Court on the weekend of 6-7 June. Entries are filling up quickly, so organisers are advising that you apply now to avoid disappointment. The camping area next to the event village is already almost 90 percent full, but extra space is available this year at a nearby rugby club. Riders will also have access to the club's showers. Organiser Michael Wilkens said: We aren't really changing anything on the course because people like it. The trail repair group are coming before the event to sort out bits and pieces in case the weather goes against us. We had a three-hour race for the first time in Cheddar last year and it was quite popular so we thought we'd bring it to Bristol. For a lot of people, a three-hour race is more 'conquerable' than a six-hour one. Having access to the rugby club means we have a second camp ground for people who don't want to be where all the action is families, for example as well as showers. It's lucky because the camping is going through the roof. He added: We've had lots of requests of riders wanting to camp next to their friends. We're doing our very best to accommodate all your requests. However, we can't guarantee that all requests will be possible due to the limited space. If you enter together in the same envelope or online then there is a good chance to get you next to each other. Please check the website for your camping pitch details.\" There will be a bar on the Friday and Saturday nights, and entertainment from a DJ and local band The Mudheads");
		//art.setText("London Business Angels announced that it is backing CitySocialising, the social network that enables outgoing professionals to connect offline with new local friends through shared interests in cities around the UK. The investment follows mentoring by Pembridge and its partners on the g2i investment readiness scheme. Launched in London in January 2007, CitySocialising subsequently rolled out sister-networks in regional cities around the UK, including Manchester and Leeds. Pre-investment, the business had already achieved annualised revenues of  300,000, based on a user subscription model, and over 23,000 members, despite being developed on a shoe-string budget. Sanchita Saha, CEO of CitySocialising attributes her success raising funding to a focus on generating revenues from day one. She will use the  260,000 raised to complete the development of a new web platform, which will include live city event listings, bespoke event creation tools, much improved social networking functionality and a site redesign, all to be launched in May. The investment site will also imminently launch in further new cities, including Newcastle, Sheffield, Liverpool and Cardiff. Sanchinta Saha says:The g2i programme was excellent. It was an opportunity to get a snapshot of every step of the investment process in bite-size chunks. It gave me business know-how ranging from finance to marketing and, most beneficially, the opportunity to network with other people who were also trying to raise funding. Having that support from people in the same boat and being able to swap stories was great. We stay in touch and they still provide a great sounding board. Pembridge Partner Hugh Mason, was one of the mentors who worked with Sanchita on the g2i programme. Hugh Mason says: One way to describe g2i would be to say that its business boot camp - a four day hike through the hard lessons of people whove actually been there and done it before, so entrepreneurs can avoid the well-known pitfalls and seize the opportunities. Sanchitas story is a classic case study: she used a tiny initial investment to create something real but basic, she played around with that until she got the formula right and only then, once shed proved that users actually wanted what she was offering with their wallets as well as their words, did she seek investment.  Hugh Mason continues: g2i is intense, but also intensely rewarding and I know all of us who share know-how on it get back as much as we give. The energy, enthusiasm and commitment of the next generation is inspiring and the timing of the City Socialising investment shows that there is still money out there for good ideas, even in these challenging times. Id encourage anyone in London who is serious about growing a business to see this time of great change as a time of great opportunity. Get set up now and you will be lean and fit to ride the wave as the economy turns upwards.");
		//art.setText("Woodley Town boss Andy Abraham can start planning for the Hellenic League after his side clinched the Reading Football League title for the first time on Saturday. Town comprehensively outgunned championship rivals YMCA 3-1 at Scours Lane to secure top spot and a place in the Hellenic Division 1 East. It was no more than a fired-up Woodley deserved and the treble is still on for Abraham s side. They face Wokingham Emmbrook at Madejski Stadium in the final of the Reading Evening Post Senior Cup on Thursday, May 14, and bring the curtain down on the season when they take on Sandhurst Devels, again at the Madejski, on Wednesday May 20. Abraham said after the game: We are all delighted to have won the league with a game to go. We set out our stall to score goals and I thought we outplayed them at times. We went with a 4-4-2 and with our two wingers pushing on, and at 3-0 up we were cruising. Right back Dan Jewell, who is only 17, was outstanding, but it was a good all-round performance from us. There was a marked contrast between the sides before the start. While YM looked relaxed, Woodley were focussed and determined. Victory for YM would have put them right back in the mix for the title, but they never looked like coming away with the points. Woodley skipper Jim Nightingale chose to play with a strong wind behind them, and Town dominated the opening period. With Craig Hiscock patrolling the midfield and wingers Billy Gordon and Tom Williams seeing plenty of the ball, it was one-way traffic as YM struggled to get out of their own half. Williams went close to giving Town the lead in the 17th minute when his 25-yard free-kick was tipped over by YM keeper Scott Mortimer. But YM s reprieve was short-lived as Nightingale flicked on the resulting corner and Hiscock fired home from six yards. Four minutes later Town s Paul Wilder sent a towering header just wide before Hiscock headed just over from another Gordon corner. YM s only chance of the first half saw Martin Abery crash a shot over in the 36th minute. But the impressive Jewell nearly added a second on the stroke of half-time when he thundered a 35-yard drive inches wide. Jewell tried again two minutes after the restart, but Wilder couldn t get out of the way of his goalbound effort. Woodley, though, went 2-0 up in the 51st minute when another surging run from Jewell set up Wilder to turn the ball in at the near post. Midfielder Drew Tipper battled hard to get YM back into the game, but their title dream evaporated in the 70th minute. Carl Davies, the top-flight s leading scorer, latched on to Hiscock s pass to poke the ball past Mortimer from the edge of the box and chalk up his 21st league goal of the season. YM rallied in the closing stages, with Johnny Adey volleying over from 20 yards and sub Steve Daley seeing his shot saved by Craig Beales. Adey did reduce the deficit with the goal of the game on 76 minutes, controlling a Tipper pass on his chest before turning to volley in a superb shot from 20 yards. YM s player/boss Mark Lemm headed against the post from a corner in injury time, but Woodley held on to spark title celebrations. Lemm said: Woodley are worthy champions they have been the most consistent side. I was really disappointed with our performance as we never got going and didn t put Woodley under any real pressure until the last 10 minutes. But a lot of that was down to Woodley who worked hard off the ball and didn t give us any room. Lemm added: We were down after the game, but the lads were saying straight away that they are all the more determined to win the league we have to accept that we weren t good enough this year. We have made great progress over the past three years. We just need to bring in two or three players to make the difference between going close and winning things.");
		//art.setText("COUNCIL tenants are to get a week off paying rent and service charges. The bonus week, which will happen some time before this autumn, will put an average of nearly 60 each in tenants' pockets. Plymouth City Council, which raised council rents by 5.88 per cent earlier this year, has agreed to take up an offer from the Government of increased subsidies for councils. The new subsidy was intended to support a cut in the level of rent increases, but the city's housing stock is being transferred to a new housing association, which will not be eligible to get the subsidy. Council officers came up with the idea of a free week to get round the restrictions. Councillors from both parties unanimously backed the plan at yesterday's meeting of the full city council. Giving the city's tenants a week off paying will cost the council 300,000, despite the Government subsidy. The free week will be between now and October, before the official launch of Plymouth Community Homes, the new not-for-profit housing association that will administer the social housing stock after a ballot of residents last autumn. Service charges will also be waived during the free week. The average council rent is 57 a week. Cllr Peter Brookshaw, the Cabinet member for housing, said the council was giving a free week rather than cutting the overall rent rise to ensure that Plymouth Community Homes started life with a clean slate. Tudor Evans, the Labour group leader on the council, said: \"To do it any other way would have presented the fledgling Plymouth Community Homes with an enormous problem. \"I understand that there are other local authorities that are not taking up this offer from the Government\" Labour councillors joined the Conservatives in giving the scheme unanimous support. Later Mr Brookshaw praised the \"cross-party working\" that had allowed the scheme to be brought in so quickly. He said: \"Plymouth is in a very unusual position. We are the only council with a transfer planned half way through this financial year. Finding a solution that is workable for tenants and Plymouth Community Homes has been challenging. \"While the council could recover the lost income, Plymouth Community Homes would not and this would have seriously affected their business plan and ability to achieve decent homes. We hope this innovative solution is the way forward.\" Clive Turner, chief executive designate of Plymouth Community Homes, said: \"The council and Plymouth Community Homes have worked really well together to come up with a fair solution.\" The council cannot yet give a date for the rent-free week as it has to take into account alterations to its accounting system. Other options such as refunding money were also considered but discounted because of the complexities of the billing and benefits systems. Cornwall Council is considering cutting rent increases to 2.4 per cent because of the new Government subsidy. In February the council set the level of the average rent increase at 3.14 (5.5 per cent). Because Cornish council tenants have already paid rent at the higher level for two months, the council is recommending an average rent increase of 1.06 a week from June 1.");
		//art.setText("PUPILS at a Plymouth school have been putting their backs into a unique environmental project. Young people at Plymstock School have been planting vegetables in a new allotment at the school and they hope to be selling them later this year to the community. Teachers Mark Taylor and Gareth Hughes have been pioneering the scheme with pupils. A special 'allotment day' was held earlier this month with about 60 pupils who helped sow the seeds of the project. They put plants in the ground and will be looking after them until it's time to take them to friends, family, the school canteen and the nearby community to sell. Mr Hughes, the school's head of business and enterprise, said: \"We found out that there was an allotment in the same position at the school in the early 1900s and we wanted to develop a new allotment on the same site. \"The development has been really successful. \"Lots of pupils have clubbed in and planted a variety of plants.\" Mr Hughes said that about 60 young people, aged from seven upwards, had been involved in the project and he hoped they would be selling some of the vegetables to the public when they grew, and also providing the school canteen with greens. It was also hoped the allotment project would be incorporated into lessons. Mr Hughes said the school had received enterprise funding from the Government in the region of 20,000 and some of that cash had been invested in the project. \"The project has started small but I hope, eventually, we will be supplying a lot of good food,\" he said. Staff from Riverford Organics visited the young people during 'allotment day' and judged some of the work which was done. A winning team from the school won a VIP trip to the Riverford Farm Shop in Staverton, near Totnes. The allotment is on a new 1,000sq metre plot. Staff and students prepared the ground with the help of a volunteer group of cadets from the Royal Naval College in Dartmouth at the start of the year. Apple and pear trees were planted, as well as dozens of raspberry bushes. Mr Hughes said that the ultimate aim was to set up a small shop from which to sell boxes of produce. Any volunteers who want to help the young people in the project can contact Mr Hughes at the school on 01752 402679. Volunteers will be subject to a Criminal Records Bureau check.");
		//art.setSource("Northern Echo, UK");
		//if(!art.getSource().toLowerCase().contains("uk")) System.out.println(art.getSource().toLowerCase());
		//locRank("London","London Business Angels announced that it is backing CitySocialising, the social network that enables outgoing professionals to connect offline with new local friends through shared interests in cities around the UK. The investment follows mentoring by Pembridge and its partners on the g2i investment readiness scheme. Launched in London in January 2007, CitySocialising subsequently rolled out sister-networks in regional cities around the UK, including Manchester and Leeds. Pre-investment, the business had already achieved annualised revenues of  300,000, based on a user subscription model, and over 23,000 members, despite being developed on a shoe-string budget. Sanchita Saha, CEO of CitySocialising attributes her success raising funding to a focus on generating revenues from day one. She will use the  260,000 raised to complete the development of a new web platform, which will include live city event listings, bespoke event creation tools, much improved social networking functionality and a site redesign, all to be launched in May. The investment site will also imminently launch in further new cities, including Newcastle, Sheffield, Liverpool and Cardiff. Sanchinta Saha says:The g2i programme was excellent. It was an opportunity to get a snapshot of every step of the investment process in bite-size chunks. It gave me business know-how ranging from finance to marketing and, most beneficially, the opportunity to network with other people who were also trying to raise funding. Having that support from people in the same boat and being able to swap stories was great. We stay in touch and they still provide a great sounding board. Pembridge Partner Hugh Mason, was one of the mentors who worked with Sanchita on the g2i programme. Hugh Mason says: One way to describe g2i would be to say that its business boot camp - a four day hike through the hard lessons of people whove actually been there and done it before, so entrepreneurs can avoid the well-known pitfalls and seize the opportunities. Sanchitas story is a classic case study: she used a tiny initial investment to create something real but basic, she played around with that until she got the formula right and only then, once shed proved that users actually wanted what she was offering with their wallets as well as their words, did she seek investment.  Hugh Mason continues: g2i is intense, but also intensely rewarding and I know all of us who share know-how on it get back as much as we give. The energy, enthusiasm and commitment of the next generation is inspiring and the timing of the City Socialising investment shows that there is still money out there for good ideas, even in these challenging times. Id encourage anyone in London who is serious about growing a business to see this time of great change as a time of great opportunity. Get set up now and you will be lean and fit to ride the wave as the economy turns upwards.");
		locRank("bristol",art);
		//nounExt(art.getText(),true);
		//doRoc();
		//doList();
	}
}
